package com.dut.bbs.async;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.text.Html.ImageGetter;
import android.util.Log;

import com.dut.bbs.R;
import com.dut.bbs.util.URLConstant;

public class URLImageParser implements ImageGetter {
	Context c;
	final int DISPLAY_WIDTH;
	static Bitmap defaultBm;
	Handler handler;
//	static {
//		int[] colors = new int[400];
//		Arrays.fill(colors, 0xff00ff00);
////		defaultBm = Bitmap.createBitmap(colors, 20, 20, Config.ARGB_8888);
//	};
	public URLImageParser(Handler handler, Context c) {
		this.handler = handler;
		this.c = c;
		defaultBm = BitmapFactory.decodeResource(c.getResources(), R.drawable.waiting);
		DISPLAY_WIDTH = c.getResources().getDisplayMetrics().widthPixels;
	}

	@Override
	public Drawable getDrawable(String source) {
		Drawable d = null;
		Boolean isOk = false;
		String fileString = URLConstant.FILEDIR_BASE
				+ String.valueOf(source.hashCode());
		Log.v("FILE", fileString);
		File file = new File(fileString);
		File fileLock = new File(fileString+".lck");
		if (file.exists() && !fileLock.exists()) {
			try{
				d = resizepic(fileString);
				isOk = true;
			}catch(Exception e){
				
			}
		}
		if (!isOk){
			try {
				d = new BitmapDrawable(defaultBm);
				d.setBounds(0, 0, defaultBm.getWidth(), defaultBm.getHeight());
				ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask(
						d);
				asyncTask.execute(source);
			} catch (Exception e) {
				return null;
			}		
		}
		return d;
	}

	public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {
		Drawable urlDrawable;

		public ImageGetterAsyncTask(Drawable d) {
			this.urlDrawable = d;
		}

		@Override
		protected void onPostExecute(Drawable result) {
			if (result != null) {
				urlDrawable.setBounds(0, 0,
						0 + result.getIntrinsicWidth(),
						0 + result.getIntrinsicHeight());
				urlDrawable = result;
				handler.sendEmptyMessage(1);
			}
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected Drawable doInBackground(String... params) {
			String source = params[0];// 图片URL
			return fetchDrawable(source);
		}

		// 获取URL的Drawable对象
		public Drawable fetchDrawable(String urlString) {
			Drawable drawable = null;
			String fileString = URLConstant.FILEDIR_BASE
					+ String.valueOf(urlString.hashCode());
			File fileLock = new File(fileString+".lck");
			if (!fileLock.exists() && handler != null){
				try {
					fileLock.createNewFile();
					URL url = new URL(urlString);
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();
					conn.setConnectTimeout(5000);
					conn.setRequestMethod("GET");
					conn.setDoInput(true);
					if (conn.getResponseCode() == 200) {
						InputStream is = conn.getInputStream();
						FileOutputStream fos = new FileOutputStream(fileString);
//						Bitmap bm = BitmapFactory.decodeStream(new FlushedInputStream(is));
//						bm.compress(CompressFormat.PNG, 80, fos);
						byte[] buffer = new byte[1024];   
		                int len = 0;   
		                while ((len = is.read(buffer)) != -1) {   
		                    fos.write(buffer, 0, len);   
		                }   
						fos.flush();
						is.close();
						fos.close();
						conn.disconnect();
//						BitmapFactory.Options options = new BitmapFactory.Options();
//						options.inSampleSize = 8;
//						options.inJustDecodeBounds = false;
//						Bitmap bmp = BitmapFactory.decodeStream(is, null, options);
//						bmp.compress(CompressFormat.PNG, 80, fos);
						fileLock.delete();
						drawable = resizepic(fileString);
					}
				} catch (Exception e) {
					return null;
				}
			}
			return drawable;
		}

//		private InputStream fetch(String urlString)
//				throws MalformedURLException, IOException {
//			HttpClient httpClient = HttpClientFactory.getHttpClient();
//			HttpGet request = new HttpGet(urlString);
//			HttpResponse response = httpClient.execute(request);
//			return response.getEntity().getContent();
//		}
	}

	class URLDrawable extends BitmapDrawable {
		protected Drawable drawable;

		@Override
		public void draw(Canvas canvas) {

			if (drawable != null) {
				drawable.draw(canvas);
			}
		}
	}
	
	Drawable resizepic(String picurl){
		BitmapFactory.Options opts = new BitmapFactory.Options();
		int destWidth = 10;
		int destHeight = 10;
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		File f = new File(picurl);
		if (f.length() < 20480) { // 0-20k
            opts.inSampleSize = 1;
        } else if (f.length() < 51200) { // 20-50k
            opts.inSampleSize = 2;
        } else if (f.length() < 307200) { // 50-300k
            opts.inSampleSize = 4;
        } else if (f.length() < 819200) { // 300-800k
            opts.inSampleSize = 6;
        } else if (f.length() < 1048576) { // 800-1024k
            opts.inSampleSize = 8;
        } else {
            opts.inSampleSize = 10;
        }
		newOpts.inJustDecodeBounds = false;
		newOpts.outHeight = destHeight;
		newOpts.outWidth = destWidth;
		Bitmap destBm = BitmapFactory.decodeFile(picurl,opts);
		Drawable drawable = new BitmapDrawable(destBm);
		int width = destBm.getWidth();
		int height = destBm.getHeight();
		if (width > DISPLAY_WIDTH) {
			double ratio = width * 1.0 / DISPLAY_WIDTH;
			width = DISPLAY_WIDTH;
			height = (int) (height / ratio);
		}
		drawable.setBounds(0, 0, width, height);
		return drawable;
	}

	static class FlushedInputStream extends FilterInputStream {
		public FlushedInputStream(InputStream inputStream) {
			super(inputStream);
		}

		@Override
		public long skip(long n) throws IOException {
			long totalBytesSkipped = 0L;
			while (totalBytesSkipped < n) {
				long bytesSkipped = in.skip(n - totalBytesSkipped);
				if (bytesSkipped == 0L) {
					int bytes = read();
					if (bytes < 0) {
						break; // we reached EOF
					} else {
						bytesSkipped = 1; // we read one byte
					}
				}
				totalBytesSkipped += bytesSkipped;
			}
			return totalBytesSkipped;
		}
	}
}
